import * as crypto from "crypto";
import camelCase from "camelcase";
import { controller_metadata, inject_metadata, provide_metadata, injectable_metadata } from "../constant";

export const Controller = (prefix: string = ""): ClassDecorator => {
  return (target) => {
    Reflect.defineMetadata(controller_metadata, { prefix, name: target.name, value: target }, target);
    Provide({ type: "controller", target });
  };
};

// 注射
export function Inject() {
  return (target: any, key: string) => {
    const type = Reflect.getMetadata("design:type", target, key);
    const injectable = Reflect.getMetadata(injectable_metadata, type); // 是否可注射的
    if (!injectable) return;
    let data = [];
    if (Reflect.hasOwnMetadata(inject_metadata, target.constructor)) {
      data = Reflect.getMetadata(inject_metadata, target.constructor);
    }
    data.push(Reflect.getMetadata(provide_metadata, type));
    Reflect.defineMetadata(inject_metadata, data, target.constructor);
  };
}
// Injectable(可注射的)
export function Injectable(): ClassDecorator {
  return (target: object) => {
    // console.log("Injectable(可注射的)", target);
    Reflect.defineMetadata(injectable_metadata, true, target);
    Provide({ type: "provide", target });
  };
}

// provide(提供);ClassDecorator
export function Provide({ type, target }: any) {
  Reflect.defineMetadata(
    provide_metadata,
    {
      type,
      uuid: crypto.randomBytes(20).toString("hex"),
      originName: target.name, // 原始名称
      name: camelCase(target.name, { pascalCase: false }),
    },
    target,
  );
}
